<script lang="ts" setup>
import { reactive, ref, watch, onMounted } from "vue"
import * as ProjectApi from "@/api/project"
import { fetchSelectList, fetchEnumSelectList } from "@/api/common"
import {
  type SaveProjectRequestData,
  type ProjectData,
  type ProjectUserRequestData,
  type ProjectUserInsertData
} from "@/api/project/types/project"
import { type UserData } from "@/api/user/types/user"
import { getRandomType } from "@/utils/common"
import { type SelectData } from "@/api/common/types/common"
import { type FormInstance, type FormRules, ElMessage, ElMessageBox, TableInstance, DrawerProps } from "element-plus"
import { Search, Refresh, CirclePlus, Delete, Edit, User } from "@element-plus/icons-vue"
import { usePagination } from "@/hooks/usePagination"
import { cloneDeep } from "lodash-es"
import { checkPermission } from "@/utils/permission"

defineOptions({
  // 命名当前组件
  name: "Project"
})

const loading = ref<boolean>(false)
const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()

//#region 增
const DEFAULT_FORM_DATA: SaveProjectRequestData = {
  id: undefined,
  name: "",
  note: "",
  duration: 0,
  durationHour: 0,
  status: "",
  jiraPrefix: "",
  type: ""
}

//project 类型下拉框
const projectTypeOptions = ref<SelectData[]>([])
const fetchProjectTypeOptions = async () => {
  const data = await fetchEnumSelectList("ProjectType")
  projectTypeOptions.value = data.data
}

//项目经理下拉框
const userSelectOptions = ref<SelectData[]>([])
const fetchUserSelectOptions = async () => {
  const data = await fetchSelectList("managerUser")
  userSelectOptions.value = data.data
}

const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<SaveProjectRequestData>(cloneDeep(DEFAULT_FORM_DATA))

// 小组 filter
const groupFilter = ref<any[]>([])
const fetchGroupFilter = async () => {
  const data = await fetchSelectList("group")
  groupFilter.value = data.data.map((sd) => ({
    text: sd.text,
    value: sd.id
  }))
}

// 判断名称是否未重复
const isNameNotRepeat = async (name: string, id: number) => {
  const { data } = await ProjectApi.checkNameRepeat(name, id)
  return data
}

const formRules: FormRules<SaveProjectRequestData> = reactive<FormRules>({
  name: [
    { required: true, trigger: "blur", message: "请输入项目名" },
    {
      validator: (rule: any, name: any, callback: any) => {
        if (name === "") {
          callback(new Error("请输入用户名"))
          return
        }
        const id = formData.value.id || 0
        if (!isNameNotRepeat(name, id)) {
          callback(new Error("项目名重复"))
        } else {
          callback()
        }
      },
      trigger: "blur"
    }
  ],
  status: [{ required: true, trigger: "blur", message: "请输入状态" }],
  jiraPrefix: [{ required: true, trigger: "blur", message: "请输入jira前缀" }],
  durationHour: [{ required: true, trigger: "blur", message: "请输入预计工时" }],
  type: [{ required: true, trigger: "blur", message: "请输入类型" }]
})

const handleCreateOrUpdate = () => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)

    loading.value = true
    ProjectApi.saveProjectDataApi(formData.value)
      .then(() => {
        ElMessage.success("操作成功")
        dialogVisible.value = false
        getTableData()
      })
      .finally(() => {
        loading.value = false
      })
  })
}
const resetForm = () => {
  formRef.value?.clearValidate()
  formData.value = cloneDeep(DEFAULT_FORM_DATA)
}
//#endregion

//#region 删
const handleDelete = (row: ProjectData) => {
  ElMessageBox.confirm(`正在删除项目：${row.name}，确认删除？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    ProjectApi.deleteProjectDataApi(row.id).then(() => {
      ElMessage.success("删除成功")
      getTableData()
    })
  })
}
//#endregion

//#region 改
const handleUpdate = (row: SaveProjectRequestData) => {
  dialogVisible.value = true
  formData.value = cloneDeep(row)
}

const handleInsert = () => {
  dialogVisible.value = true
  formData.value = cloneDeep(DEFAULT_FORM_DATA)
  formData.value.status = "OPEN"
}
//#endregion

//#region 查
const tableData = ref<ProjectData[]>([])
const searchFormRef = ref<FormInstance | null>(null)
const searchData = reactive({
  name: "",
  status: "",
  jiraPrefix: "",
  type: "",
  createId: undefined
})
const getTableData = () => {
  loading.value = true
  ProjectApi.getProjectDataApi({
    page: paginationData.currentPage,
    size: paginationData.pageSize,
    name: searchData.name || undefined,
    status: searchData.status || undefined,
    jiraPrefix: searchData.jiraPrefix,
    type: searchData.type,
    createId: searchData.createId || undefined
  })
    .then(({ data }) => {
      paginationData.total = data.total
      tableData.value = data.datas
    })
    .catch(() => {
      tableData.value = []
    })
    .finally(() => {
      loading.value = false
    })
}
const handleSearch = () => {
  paginationData.currentPage === 1 ? getTableData() : (paginationData.currentPage = 1)
}
const resetSearch = () => {
  searchFormRef.value?.resetFields()
  handleSearch()
}
//#endregion
//更新项目状态
const updateStatus = (row: ProjectData) => {
  const id = row.id
  if (!id) return
  const status = row.status
  const text = status == "CLOSED" ? "OPEN" : "CLOSED"
  ElMessageBox.confirm(`确认${text}项目吗`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    ProjectApi.updateStatusApi(id, text).then(() => {
      ElMessage.success("状态修改成功")
      getTableData()
    })
  })
}

// 人员管理 抽屉 start *************************************
const drawer = ref(false)
const direction = ref<DrawerProps["direction"]>("rtl")
// 选择项目人员时候的查询条件
const projectUsertSearchData = ref<ProjectUserRequestData>({
  projectId: 0
})
//项目下人员列表
const projectUser = ref<UserData[]>([])

//获取项目下的用户
const getProjectUser = async (projectId: number | undefined) => {
  if (projectId === undefined) {
    projectUser.value = []
  } else {
    const { data } = await ProjectApi.projectUserDataApi(projectId)
    projectUser.value = data
  }
}

//打开抽屉：项目人员详情
const openDrawer = (row: ProjectData) => {
  drawer.value = true
  formData.value = cloneDeep(row)
  projectUsertSearchData.value.projectId = row.id
  getProjectUser(row.id)
}
const handleProjectUserDelete = (row: UserData) => {
  ElMessageBox.confirm(`确定从项目中删除【${row.userName}】吗?`, "确认", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    const projectId = formData.value.id || 0
    const userId = row.id || 0
    ProjectApi.deleteProjectUserApi(projectId, userId).then(() => {
      ElMessage.success("删除成功")
      getProjectUser(projectId)
    })
  })
}

function confirmClick() {
  drawer.value = false
}
// 人员管理 抽屉 end *************************************

// 人员选择 弹出框 start
const userDialogVisible = ref(false)
//待选用户 table ref
const userTableRef = ref<TableInstance>()

//待选人员列表
const userData = ref<UserData[]>([])
//打开新增人员窗口
const handleInsertUser = async () => {
  userDialogVisible.value = true
  const { data } = await ProjectApi.projectSelectUserListApi(projectUsertSearchData.value)
  userData.value = data
}
const filterGroup = (value: number, row: UserData) => {
  return row.groupId === value
}

//选择用户事件
const multipleUserSelection = ref<UserData[]>([])
const handleSelectionUserChange = (val: UserData[]) => {
  multipleUserSelection.value = val
}
// 点击行选中行
const handleUserRowClick = (row: UserData) => {
  if (userTableRef.value) {
    const isSelected = multipleUserSelection.value.includes(row)
    // 切换行的选中状态
    userTableRef.value.toggleRowSelection(row, !isSelected)
  }
}
//确认选择
const handleSelectUser = () => {
  ElMessageBox.confirm(
    `确定添加当前【${multipleUserSelection.value.length}】个用户到项目【${formData.value.name}】吗`,
    "提示",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    }
  ).then(() => {
    const data: ProjectUserInsertData = {
      projectId: formData.value.id || 0,
      userIds: multipleUserSelection.value.map((row) => row.id).filter((id) => id !== undefined && id !== null)
    }
    ProjectApi.insertProjectUserApi(data).then(() => {
      ElMessage.success("添加成功")
      getProjectUser(formData.value.id)
      userDialogVisible.value = false
    })
  })
}
// 人员选择弹出框 end

/** 监听分页参数的变化 */
watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
onMounted(() => {
  fetchGroupFilter()
  fetchProjectTypeOptions()
  fetchUserSelectOptions()
})
</script>

<template>
  <div class="app-container">
    <el-card v-loading="loading" shadow="never" class="search-wrapper">
      <el-form ref="searchFormRef" :inline="true" :model="searchData" size="small">
        <el-form-item prop="name" label="项目名">
          <el-input v-model="searchData.name" placeholder="请输入" />
        </el-form-item>

        <el-form-item prop="type" label="项目类型">
          <el-select
            v-model="searchData.type"
            clearable
            filterable
            placeholder="请选择项目类型"
            style="width: 160px"
            :empty-values="[null]"
          >
            <el-option v-for="item in projectTypeOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="jiraPrefix" label="Jira前缀">
          <el-input v-model="searchData.jiraPrefix" placeholder="请输入" />
        </el-form-item>

        <el-form-item prop="createId" label="项目经理">
          <el-select
            v-model="searchData.createId"
            clearable
            filterable
            placeholder="请选项目经理"
            style="width: 160px"
            :empty-values="[null]"
          >
            <el-option v-for="item in userSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="status" label="状态">
          <el-select
            v-model="searchData.status"
            filterable
            clearable
            allow-create
            default-first-option
            :reserve-keyword="false"
            placeholder="选择或输入状态"
            style="width: 160px"
          >
            <el-option value="CLOSED" label="CLOSED" />
            <el-option value="OPEN" label="OPEN" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
          <el-button :icon="Refresh" @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card v-loading="loading" shadow="never">
      <div class="toolbar-wrapper">
        <div>
          <el-button type="primary" :icon="CirclePlus" @click="handleInsert" v-permission="['admin', 'manager']"
            >新增项目</el-button
          >
          <!-- <el-button type="danger" :icon="Delete">批量删除</el-button> -->
        </div>
        <div>
          <!-- <el-tooltip content="刷新当前页">
            <el-button type="primary" :icon="RefreshRight" circle @click="getTableData" />
          </el-tooltip> -->
        </div>
      </div>
      <div class="table-wrapper">
        <el-table :data="tableData" stripe :border="true" size="small">
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column
            prop="name"
            label="项目名称"
            header-align="center"
            align="left"
            width="240"
            show-overflow-tooltip
          />
          <el-table-column prop="status" label="状态" align="center" width="100">
            <template #default="scope">
              <el-tag :type="scope.row.status === 'CLOSED' ? 'success' : 'info'" effect="light">{{
                scope.row.status
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="typeText" label="类型" align="center" />
          <el-table-column prop="jiraPrefix" label="jira前缀" align="center" />
          <el-table-column prop="durationHour" label="预计工时(小时)" align="center" />
          <el-table-column prop="usedTimeHour" label="已用工时" align="center" />
          <el-table-column prop="createName" label="项目经理" align="center" />
          <el-table-column prop="createTime" label="创建时间" align="center" />
          <el-table-column fixed="right" label="操作" width="240" align="center">
            <template #default="scope">
              <el-button
                :type="scope.row.status === 'CLOSED' ? 'info' : 'warning'"
                size="small"
                @click="updateStatus(scope.row)"
                v-if="checkPermission(['admin', 'manager'])"
                >{{ scope.row.status === "CLOSED" ? "打开" : "关闭" }}</el-button
              >
              <el-button
                type="primary"
                :icon="Edit"
                bg
                size="small"
                @click="handleUpdate(scope.row)"
                title="编辑"
                v-if="checkPermission(['admin', 'manager'])"
              />
              <el-button type="success" :icon="User" bg size="small" @click="openDrawer(scope.row)" title="人员管理" />
              <el-button
                type="danger"
                :icon="Delete"
                bg
                size="small"
                @click="handleDelete(scope.row)"
                title="删除"
                v-if="checkPermission(['admin', 'manager'])"
              />
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pager-wrapper">
        <el-pagination
          background
          :layout="paginationData.layout"
          :page-sizes="paginationData.pageSizes"
          :total="paginationData.total"
          :page-size="paginationData.pageSize"
          :currentPage="paginationData.currentPage"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
    <!-- 新增/修改 -->
    <el-dialog
      v-model="dialogVisible"
      :title="formData.id === undefined ? '新增项目' : '修改项目'"
      @closed="resetForm"
      width="40%"
    >
      <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" label-position="left">
        <el-form-item prop="name" label="项目名">
          <el-input v-model="formData.name" placeholder="请输入" />
        </el-form-item>

        <el-form-item prop="type" label="类型">
          <el-select v-model="formData.type" clearable placeholder="请选择类型">
            <el-option v-for="item in projectTypeOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="jiraPrefix" label="jira前缀">
          <el-input v-model="formData.jiraPrefix" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="status" label="状态">
          <el-select
            v-model="formData.status"
            filterable
            clearable
            allow-create
            default-first-option
            :reserve-keyword="false"
            placeholder="选择或输入状态"
          >
            <el-option value="OPEN" label="OPEN" />
            <el-option value="CLOSED" label="CLOSED" />
          </el-select>
        </el-form-item>
        <el-form-item prop="note" label="备注">
          <el-input v-model="formData.note" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="durationHour" label="预计工时">
          <el-input-number
            v-model="formData.durationHour"
            :min="1"
            :max="16000"
            :step="0.5"
            step-strictly
            placeholder="单位:小时"
            style="width: 100%"
          >
            <template #suffix>
              <span>小时</span>
            </template>
          </el-input-number>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleCreateOrUpdate" :loading="loading">确认</el-button>
      </template>
    </el-dialog>

    <!--项目人员管理 抽屉 start-->
    <el-drawer
      v-model="drawer"
      :direction="direction"
      size="60%"
      :close-on-click-modal="false"
      :show-close="false"
      :with-header="false"
    >
      <template #default>
        <h4>
          <el-text style="color: #67c23a" size="large">{{ formData.name }}</el-text> 人员管理
        </h4>
        <div class="toolbar-wrapper">
          <div>
            <el-button type="primary" :icon="CirclePlus" @click="handleInsertUser">新增人员</el-button>
          </div>
          <div />
        </div>
        <div class="table-wrapper">
          <el-table :data="projectUser" stripe :border="true">
            <el-table-column prop="userName" label="用户名" align="center" />
            <el-table-column prop="userCode" label="工号" align="center" />
            <el-table-column prop="groupName" label="小组" align="center" />
            <el-table-column fixed="right" label="操作" align="center" v-if="checkPermission(['admin', 'manager'])">
              <template #default="scope">
                <el-button
                  type="danger"
                  text
                  bg
                  size="small"
                  @click="handleProjectUserDelete(scope.row)"
                  v-if="checkPermission(['admin', 'manager'])"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </div>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button type="primary" @click="confirmClick">关闭</el-button>
        </div>
      </template>
    </el-drawer>
    <!--项目人员管理 抽屉 end-->

    <!-- 人员选择弹出框 start -->
    <el-dialog v-model="userDialogVisible" title="点击行或勾选复选框以选择人员" @closed="userData = []" width="40%">
      <div class="table-wrapper">
        <el-table
          :data="userData"
          stripe
          :border="true"
          height="400"
          ref="userTableRef"
          @selection-change="handleSelectionUserChange"
          @row-click="handleUserRowClick"
        >
          <el-table-column type="selection" width="50" align="center" v-if="checkPermission(['admin', 'manager'])" />
          <el-table-column prop="userName" label="用户名" align="center" />
          <el-table-column prop="userCode" label="工号" align="center" />
          <el-table-column
            prop="groupName"
            label="小组"
            align="center"
            :filters="groupFilter"
            :filter-method="filterGroup"
            filter-placement="bottom-end"
          >
            <template #default="scope">
              <el-tag :type="getRandomType(scope.row.groupId)" effect="dark" round> {{ scope.row.groupName }}</el-tag>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <el-button @click="userDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="handleSelectUser"
          :loading="loading"
          v-permission="['admin', 'manager']"
          :disabled="multipleUserSelection.length === 0"
          >确认选择</el-button
        >
      </template>
    </el-dialog>

    <!-- 人员选择弹出框 end -->
  </div>
</template>

<style lang="scss" scoped>
.search-wrapper {
  margin-bottom: 20px;

  :deep(.el-card__body) {
    padding-bottom: 2px;
  }
}

.toolbar-wrapper {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.table-wrapper {
  margin-bottom: 20px;
}

.pager-wrapper {
  display: flex;
  justify-content: flex-end;
}
</style>
